#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <string.h>
#include <ctype.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h>
#include <errno.h>
#include <time.h>

#include "sockets.adp.h"

/***********************************************************
 * Shorcut para connect
 *  0 --> CONNECTION_OK
 * -1 --> CONNECTION_SOCKET_ERROR
 * -2 --> CONNECTION_CONNECT_ERROR
 ***********************************************************/
int tryToConnect(unsigned int* puertodestino, unsigned char* ipdestino, short int* socketaasociar){

	struct sockaddr_in address;
	int fd;

	/*-- Llamada a socket --*/
	fd = socket(AF_INET, SOCK_STREAM, 0);

	/*-- Si hay problemas con la llamada a socket --*/
	if(fd == -1)
		return CONNECTION_SOCKET_ERROR;

	*socketaasociar = fd;

	/*-- Armado De La Estructura Destino --*/	
	address.sin_addr.s_addr = inet_addr((const char*)ipdestino);
	address.sin_port = htons(*puertodestino);
	address.sin_family = AF_INET;

	memset(&(address.sin_zero),'\0',8);

	if(connect(*socketaasociar, (struct sockaddr*)&address, sizeof(struct sockaddr)) == -1)
		return CONNECTION_CONNECT_ERROR;

	return CONNECTION_OK;
}


/***********************************************************
 * 
 * Funcion que recibe un puerto y lo prepara para escuchar
 * conexiones entrantes
 *
 ***********************************************************/
int prepareListenPort(unsigned short int port, short int* socketPointer){

	struct sockaddr_in address;
	int fd;

	fd = socket(AF_INET, SOCK_STREAM, 0);

	/*-- Algun problema al hacer socket --*/
	if (fd == -1){
		return CONNECTION_SOCKET_ERROR;	
	}		
		
	address.sin_family = AF_INET;
	address.sin_port = htons(port);
	address.sin_addr.s_addr = INADDR_ANY;

	/*-- Hacemos el bind --*/
	if(bind(fd, (struct sockaddr *)&address, sizeof (address)) == -1){
		close(fd);
		return CONNECTION_BIND_ERROR;
	}
	
	/* Se avisa al sistema que comience a atender llamadas de clientes */
	if (listen(fd, 1) == -1){
		close (fd);
		return CONNECTION_LISTEN_ERROR;
	}
	
	/*-- Asigno descriptor de socket obtenido al puntero --*/
	*socketPointer = fd;
	
	return CONNECTION_LISTEN_OK;
}
